package net.xdclass.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.NewUserCouponRequest;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.enums.SendCodeEnums;
import net.xdclass.exception.BizException;
import net.xdclass.feign.CouponFeignService;
import net.xdclass.interceptor.LoginInterceptor;
import net.xdclass.mapper.UserMapper;
import net.xdclass.model.LoginUser;
import net.xdclass.model.UserDO;
import net.xdclass.request.UserLoginRequest;
import net.xdclass.request.UserRegisterRequest;
import net.xdclass.service.NotifyService;
import net.xdclass.service.UserService;
import net.xdclass.utils.CommonUtils;
import net.xdclass.utils.JWTUtils;
import net.xdclass.utils.JsonData;
import net.xdclass.vo.UserVO;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private CouponFeignService couponFeignService;

    @Autowired
    private NotifyService notifyService;

    @Autowired
    private UserMapper userMapper;

    @Override
    public JsonData register(UserRegisterRequest registerRequest) {
        // 校驗驗証碼
        boolean checkCode = false;
        if (StringUtils.isNotBlank(registerRequest.getMail())) {
            checkCode = notifyService.checkCode(SendCodeEnums.USER_REGISTER, registerRequest.getMail(), registerRequest.getCode());
        }

        if (!checkCode) {
            return JsonData.buildResult(BizCodeEnum.CODE_ERROR);
        }

        // 插入注冊用戶數據
        UserDO userDO = new UserDO();
        BeanUtils.copyProperties(registerRequest, userDO);
        userDO.setCreateTime(new Date());
        userDO.setSlogan(registerRequest.getSlogan());

        // 加密密碼
        userDO.setSecret("$1$" + CommonUtils.getStringNumRandom(8));
        // 加鹽處理
        String cryptPwd = Md5Crypt.md5Crypt(registerRequest.getPwd().getBytes(), userDO.getSecret());
        userDO.setPwd(cryptPwd);

        // 校驗唯一性
        if (checkUnique(userDO.getMail())) {
            int row = userMapper.insert(userDO);
            log.info("rows: {}, 注冊成功: {}", row, userDO.toString());
            userRegisterInitTask(userDO);
            return JsonData.buildSuccess();
        } else {
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_PWD_ERROR);
        }
    }
    @Override
    public JsonData login(UserLoginRequest userLoginRequest) {
        List<UserDO> userDoList = userMapper.selectList(new QueryWrapper<UserDO>().eq("mail", userLoginRequest.getMail()));

        // 确保郵箱賬號是唯一的
        if (userDoList != null && userDoList.size() == 1) {
            UserDO userDO = userDoList.get(0);
            String cryptPwd = Md5Crypt.md5Crypt(userLoginRequest.getPwd().getBytes(), userDO.getSecret());
            if (cryptPwd.equals(userDO.getPwd())) {
                LoginUser loginUser = new LoginUser();
                BeanUtils.copyProperties(userDO, loginUser);
                String token = JWTUtils.generateJSONWebToken(loginUser);
                return JsonData.buildSuccess(token);
            } else {
               return JsonData.buildResult(BizCodeEnum.ACCOUNT_PWD_ERROR);
            }
        } else {
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_PWD_ERROR);
        }
    }


    /**
     * 校驗賬號唯一性
     * @param mail
     * @return
     */
    private boolean checkUnique(String mail) {
        List<UserDO> list =  userMapper.selectList(new QueryWrapper<UserDO>().eq("mail", mail));
        return list.size() > 0 ? false : true;
    }

    /**
     * 初始化用戶注冊后一系列動作, 如發放褔利等
     * @param userDo
     */
    private void userRegisterInitTask(UserDO userDo) {
        NewUserCouponRequest request = new NewUserCouponRequest();
        request.setName(userDo.getName());
        request.setUserId(userDo.getId());
        JsonData jsonData = couponFeignService.addNewUserCoupon(request);
        log.info("發放新用戶注冊优惠券: {}, 結果: {}", request.toString(), jsonData.toString());
    }

    @Override
    public UserVO findUserDetail() {
        LoginUser loginUser = (LoginUser) LoginInterceptor.threadLocal.get();
        UserDO userDO = userMapper.selectOne(new QueryWrapper<UserDO>().eq("id", loginUser.getId()));
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userDO, userVO);

        return userVO;
    }
}
